/*
 * This file is part of the Try! Engine project.
 *
 * Copyright 2010-2011 Emanuele Bertoldi. All rights reserved.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * You should have received a copy of the modified BSD License along with this
 * program. If not, see <http://www.opensource.org/licenses/bsd-license.php>
 */

#include "toolbox.h"
#include <view3d.h>
#include <toolmodellist.h>
#include <projectmodellist.h>
#include <QtDeclarative/QDeclarativeContext>
#include <QtDeclarative/QDeclarativeEngine>
#include <QtGui/QMainWindow>

using namespace Try;

ToolBox::ToolBox(QWidget* parent)
    :   QDeclarativeView(parent)
{
    this->setObjectName("toolBox");
    this->setEnabled(false);

    this->setWindowFlags(this->windowFlags() | Qt::Tool);
    this->setResizeMode(QDeclarativeView::SizeRootObjectToView);
    this->setWindowTitle(tr("Tools"));
    this->resize(40, 400);

    if (parent)
        parent->installEventFilter(this);

    QObject::connect(ProjectModelList::instance(), SIGNAL(projectLoaded(Project*)), this, SLOT(onProjectLoaded(Project*)));
    QObject::connect(ProjectModelList::instance(), SIGNAL(projectClosed(Project*)), this, SLOT(onProjectClosed(Project*)));

    QDeclarativeEngine* engine = this->engine();
    QDeclarativeContext* ctxt = engine->rootContext();

    ctxt->setContextProperty("widget", this);
    ctxt->setContextProperty("tools", ToolModelList::instance());

    this->setSource(QUrl("data/ui/ToolBox.qml"));
}

ToolBox::~ToolBox()
{
}

void ToolBox::activate(int id)
{
    ToolModelList* tools = ToolModelList::instance();

    if (id < tools->rowCount())
    {
        Tool* tool = tools->toolAt(id);

        if (tool)
        {
            QMainWindow* main = qobject_cast<QMainWindow*>(this->parentWidget());
            View3d* view3d = qobject_cast<View3d*>(main->centralWidget());

            tool->activate(view3d);
        }
    }
}

bool ToolBox::eventFilter(QObject* watched, QEvent* evt)
{
    if (watched)
    {
        switch (evt->type())
        {
        case QEvent::Show:
            this->setVisible(true);
            break;

        case QEvent::Hide:
            this->setVisible(false);
            break;

        case QEvent::Move:
        case QEvent::Resize:
            this->moveToDefaultPosition();
            break;

        default:
            break;
        }
    }

    return false;
}

void ToolBox::showEvent(QShowEvent* evt)
{
    Q_UNUSED(evt)

    this->moveToDefaultPosition();

    emit visible(true);
}

void ToolBox::hideEvent(QHideEvent* evt)
{
    Q_UNUSED(evt)

    emit visible(false);
}

void ToolBox::changeEvent(QEvent* evt)
{
    Q_UNUSED(evt)

    emit enabled(this->isEnabled());
}

void ToolBox::onProjectLoaded(Project* project)
{
    if (project)
    {
        this->setEnabled(true);

        this->activate(0);
    }
}

void ToolBox::onProjectClosed(Project* project)
{
    if (project)
    {
        this->setEnabled(false);
    }
}

void ToolBox::moveToDefaultPosition()
{
    QWidget* parent = this->parentWidget();

    if (parent)
    {
        int x = parent->x();
        int y = parent->y();
        int height = parent->height();

        this->move(x + 20, y + (height-this->height())/2);
    }
}
